package com.gjy.zk.controller;

import com.gjy.zk.common.Result;
import com.gjy.zk.util.ZookeeperUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-09-29 18:02:13
 */
@Slf4j
@RestController
@RequestMapping("/zk")
@Tag(name = "Zookeeper操作接口", description = "Zookeeper相关操作API")
public class ZookeeperController {

    @Resource
    private ZookeeperUtil zookeeperUtil;

    @GetMapping("/checkConnection")
    @Operation(summary = "检查Zookeeper连接状态")
    public Result<Boolean> checkConnection() {
        try {
            boolean connected = zookeeperUtil.isConnected();
            return Result.success("连接状态检查完成", connected);
        } catch (Exception e) {
            log.error("检查连接状态失败", e);
            return Result.error("检查连接状态失败: " + e.getMessage());
        }
    }

    @PostMapping("/create/persistent")
    @Operation(summary = "创建持久节点")
    public Result<String> createPersistentNode(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "节点数据") @RequestParam(defaultValue = "") String data) {
        try {
            String resultPath = zookeeperUtil.createPersistentNode(path, data);
            return Result.success("持久节点创建成功", resultPath);
        } catch (Exception e) {
            log.error("创建持久节点失败", e);
            return Result.error("创建持久节点失败: " + e.getMessage());
        }
    }

    @PostMapping("/create/ephemeral")
    @Operation(summary = "创建临时节点")
    public Result<String> createEphemeralNode(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "节点数据") @RequestParam(defaultValue = "") String data) {
        try {
            String resultPath = zookeeperUtil.createEphemeralNode(path, data);
            return Result.success("临时节点创建成功", resultPath);
        } catch (Exception e) {
            log.error("创建临时节点失败", e);
            return Result.error("创建临时节点失败: " + e.getMessage());
        }
    }

    @PostMapping("/create/sequential")
    @Operation(summary = "创建顺序节点")
    public Result<String> createSequentialNode(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "节点数据") @RequestParam(defaultValue = "") String data) {
        try {
            String resultPath = zookeeperUtil.createSequentialNode(path, data);
            return Result.success("顺序节点创建成功", resultPath);
        } catch (Exception e) {
            log.error("创建顺序节点失败", e);
            return Result.error("创建顺序节点失败: " + e.getMessage());
        }
    }

    @PostMapping("/create/async")
    @Operation(summary = "异步创建节点")
    public Result<String> createNodeAsync(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "节点数据") @RequestParam(defaultValue = "") String data,
            @Parameter(description = "节点类型", example = "PERSISTENT") @RequestParam(defaultValue = "PERSISTENT") String mode) {
        try {
            CountDownLatch latch = new CountDownLatch(1);
            CreateMode createMode = CreateMode.valueOf(mode);

            zookeeperUtil.createNodeAsync(path, data, createMode, (client, event) -> {
                log.info("异步创建节点完成: {}", event.getPath());
                latch.countDown();
            });

            latch.await();
            return Result.success("异步创建节点请求已提交");
        } catch (Exception e) {
            log.error("异步创建节点失败", e);
            return Result.error("异步创建节点失败: " + e.getMessage());
        }
    }

    @GetMapping("/exists")
    @Operation(summary = "检查节点是否存在")
    public Result<Boolean> exists(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            boolean exists = zookeeperUtil.exists(path);
            return Result.success("节点存在性检查完成", exists);
        } catch (Exception e) {
            log.error("检查节点存在性失败", e);
            return Result.error("检查节点存在性失败: " + e.getMessage());
        }
    }

    @GetMapping("/getData")
    @Operation(summary = "获取节点数据")
    public Result<String> getData(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            String data = zookeeperUtil.getData(path);
            return Result.success("获取节点数据成功", data);
        } catch (Exception e) {
            log.error("获取节点数据失败", e);
            return Result.error("获取节点数据失败: " + e.getMessage());
        }
    }

    @PutMapping("/setData")
    @Operation(summary = "设置节点数据")
    public Result<String> setData(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "节点数据", required = true) @RequestParam String data) {
        try {
            Stat stat = zookeeperUtil.setData(path, data);
            return Result.success("设置节点数据成功", "版本号: " + stat.getVersion());
        } catch (Exception e) {
            log.error("设置节点数据失败", e);
            return Result.error("设置节点数据失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除节点")
    public Result<String> deleteNode(
            @Parameter(description = "节点路径", required = true) @RequestParam String path,
            @Parameter(description = "是否强制删除", example = "false") @RequestParam(defaultValue = "false") boolean force) {
        try {
            if (force) {
                zookeeperUtil.deleteNodeForce(path);
                return Result.success("强制删除节点成功");
            } else {
                zookeeperUtil.deleteNode(path);
                return Result.success("删除节点成功");
            }
        } catch (Exception e) {
            log.error("删除节点失败", e);
            return Result.error("删除节点失败: " + e.getMessage());
        }
    }

    @GetMapping("/children")
    @Operation(summary = "获取子节点列表")
    public Result<List<String>> getChildren(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            List<String> children = zookeeperUtil.getChildren(path);
            return Result.success("获取子节点列表成功", children);
        } catch (Exception e) {
            log.error("获取子节点列表失败", e);
            return Result.error("获取子节点列表失败: " + e.getMessage());
        }
    }

    @GetMapping("/stat")
    @Operation(summary = "获取节点状态信息")
    public Result<Stat> getStat(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            Stat stat = zookeeperUtil.getStat(path);
            return Result.success("获取节点状态成功", stat);
        } catch (Exception e) {
            log.error("获取节点状态失败", e);
            return Result.error("获取节点状态失败: " + e.getMessage());
        }
    }

    @PostMapping("/watch/node")
    @Operation(summary = "监听节点变化")
    public Result<String> watchNode(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            zookeeperUtil.watchNode(path);
            return Result.success("节点监听已启动");
        } catch (Exception e) {
            log.error("启动节点监听失败", e);
            return Result.error("启动节点监听失败: " + e.getMessage());
        }
    }

    @PostMapping("/watch/children")
    @Operation(summary = "监听子节点变化")
    public Result<String> watchChildren(
            @Parameter(description = "节点路径", required = true) @RequestParam String path) {
        try {
            zookeeperUtil.watchChildren(path);
            return Result.success("子节点监听已启动");
        } catch (Exception e) {
            log.error("启动子节点监听失败", e);
            return Result.error("启动子节点监听失败: " + e.getMessage());
        }
    }

}
